package com.calis.ill.order.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.calis.ill.order.entity.Order;
import com.calis.ill.order.entity.OrderItem;
import com.calis.ill.order.entity.Product;
import com.calis.ill.order.entity.User;
import com.calis.ill.order.repository.OrderRepository;
import com.calis.ill.order.repository.ProductRepository;
import com.calis.ill.order.repository.UserRepository;
import com.calis.ill.order.service.api.OrderService;
import com.calis.ill.order.service.api.vo.OrderItemVO;
import com.calis.ill.order.service.api.vo.OrderVO;
import com.fasterxml.jackson.databind.ObjectMapper;

@Service("orderService")
public class OrderServiceImpl implements OrderService{
	
	@Autowired
	OrderRepository repo;
	
	@Autowired
	UserRepository userRepo;
	
	@Autowired
	ProductRepository productRepo;
	
	ObjectMapper mapper = new ObjectMapper();
	


	@Transactional
	public void create(String account, List<OrderItemVO> items) throws Exception {
		Order order = new Order();
		order.setSn(UUID.randomUUID().toString());
		double totalPrice = 0;
		List<OrderItem> orderItems = new ArrayList<OrderItem>();
		List<Product> products = new ArrayList<Product>();
		for(OrderItemVO item: items){
			OrderItem o = new OrderItem();
			o.setCode(item.getCode());
			o.setQuantity(item.getQuantity());
			o.setOrder(order);
			
			Product p = productRepo.findByCode(o.getCode());
			Long stock = p.getStock()-o.getQuantity();
			if( stock < 0){
				throw new RuntimeException(p.getTitle() + " is not enough product");
			}
			p.setStock(stock);
			products.add(p);
			
			totalPrice += p.getPrice() * o.getQuantity();
			orderItems.add(o);
		}
		productRepo.save(products);
		order.setOrderItems(orderItems);
		order.setTotalPrice(totalPrice);
		
		User user = userRepo.findByAccount(account);
		
		BigDecimal balance = user.getBalance().subtract(new BigDecimal(totalPrice));
		
		if(balance.doubleValue() < 0){
			throw new RuntimeException("Balance is not enough");
		}
		user.setBalance(balance);
		userRepo.save(user);
		
		order.setUser(user);
		order.setStatus(1);
		order.setCreateTime(new Date());
		repo.save(order);
	}
	
	public List<OrderVO> getMyOrders(String account) throws Exception{
		List<OrderVO> rst = new ArrayList<OrderVO>();
		List<Order> orders = repo.findByUser_Account(account);
		for(Order order : orders){
			OrderVO vo = new OrderVO();
			vo.setCreateTime(order.getCreateTime());
			vo.setSn(order.getSn());
			vo.setStatus(order.getStatus());
			vo.setTotalPrice(order.getTotalPrice());
			List<OrderItemVO> itemVOs = new ArrayList<OrderItemVO>();
			for(OrderItem item : order.getOrderItems()){
				OrderItemVO itemVO = new OrderItemVO();
				itemVO.setCode(item.getCode());
				itemVO.setQuantity(item.getQuantity());
				itemVOs.add(itemVO);
			}
			vo.setOrderItems(itemVOs);
			rst.add(vo);
		}
		return rst;
	};

}
